Repository navigation
feat(oracle): bond escrow, bounty settlement and provider slashing (SC-023) - #705
Closed
ahsen198911-debug wants to merge 6 commits into
Closed
ahsen198911-debug wants to merge 6 commits into
ahsen198911-debug wants to merge 6 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements [SC-023] — Oracle Marketplace Contract with Provider Registration & Escrow Bounties.
The
oracle_marketplacecrate already had a skeleton: register / deregister / rate / select. What it did not have was any of the three acceptance criteria. This PR adds them.register_oraclenow pullsinitial_bondinto the contract's custody via a real SAC transfer before the provider is listed.increase_bondtops it up,withdraw_bondreleases it after the deregistration cooldown, and it can only be withdrawn while inactive.create_call_escrowescrows the caller's bounty;resolve_call(…, Accurate)paysoracle.fee_bpsto the provider and the remainder to the admin. Payout state is written before the transfer so a re-entrant token cannot re-trigger it.resolve_call(…, Inaccurate)refunds the caller's bounty in full and slashesconfig.slash_penalty_bpsof the bond, split between the harmed caller and the admin.Verification actually run
Rust 1.98.1, soroban-sdk 23.5.3, against the workspace's own
Cargo.lock(which pins the compatibleed25519-dalek2.2.0 — a fresh resolve pulls 3.0.0 andsoroban-env-hostfails to compile, so the lock is required).26 tests, exercised against real SACs registered in the test env rather than mocks, so every balance asserted is a balance that was actually moved:
initial_bond < min_stakerejectedfee_bpsmin_stakefloor cannot be slashed againThree bugs the tests caught, and how I handled each
total_resolvedwas never persisted. TheAccuratebranch incremented the counter and then dropped it. Fixed in the contract withset_oracle.Slashing was structurally impossible.
min_stakewas both the registration bond and the slash floor, sostaked_amount == min_stakeon registration and theSlashBelowMinStakeguard fired on the first dispute — every provider was unfalsifiable. I split the two concepts:min_stakeis the floor,initial_bondis what they post up front, and registration requiresinitial_bond >= min_stake. Now a provider has real collateral at risk and the floor still bounds the blast radius.My own test captured a balance after the debit.
inaccurate_resolution_refunds_caller_and_slashes_bondreadcaller_fee_beforeaftercreate_call_escrow, so "refunded in full" was compared against an already-debited balance. The contract was correct; the test was wrong. Fixed by capturing before the escrow, with a comment explaining why the order matters.Design decisions worth reviewing
slash_penalty_bpsis split 50/50 between the caller and the admin. The caller was actively served a bad answer; the admin runs the marketplace. Easy to change if the intended split differs.min_stakefloor is refused a further slash rather than being pushed below it. The alternative is capping the slash at the remaining balance, which is also defensible — worth agreeing on before merge.initializegained aslash_penalty_bpsparameter. This is a breaking change to the existinginitializesignature. The three pre-existing tests are updated to match, but any deployed contract would need a migration. Flagging it deliberately rather than leaving it implicit.Notes
feature/sc-023-sc023-slugper the issue, notmain.Cargo.toml: removed the unusedbackit-shareddependency; nothing in the crate referenced it, and dropping it keeps the build to a single crate.escrow_for_unknown_oracle_is_rejected,escrow_for_inactive_oracle_is_rejected) alongside the happy path.